/*
 *  SnpCheckInStory.cpp
 *  AMPlugin
 *
 *  Created by Vu Tiet on 6/13/12.
 *  Copyright 2012 __MyCompanyName__. All rights reserved.
 *
 */

#include "VCPlugInHeaders.h"

// Interface includes:
#include "ITextTarget.h"
#include "IIDMLComponentName.h"
#include "ProgressBar.h"
#include "ISnippetExport.h"
#include "AMPCAlert.h"

// General includes:
#include "StreamUtil.h"
#include "SDKFileHelper.h"
#include "LocaleSetting.h"


// Framework includes:
#include "AMPID.h"
#include "ISnpRunnableContext.h"
#include "SnpRunnable.h"
#include "ISnipRunParameterUtils.h"
#include "SnpTextModelHelper.h"
#if __INTEL_COMPILER || MACINTOSH
#include "K2Vector.tpp"
#endif
// SDK includes:
#include "SDKLayoutHelper.h"

#include "StringUtils.h"
#include "AMGlobal.h"
#include "HTTPRequestHelper.h"
#include "IGraphicFrameData.h"
#include <iostream>

#include "ISnippetImport.h"
#include "AMPLogDataRecord.h"
#include "ISelectionManager.h"
#include "IStoryList.h"
#include "SDKLayoutHelper.h"
#include "ISpreadList.h"
#include "ISnippetImport.h"
#include "AMPIconFrameUpdate.h"
#include "K2Vector.tpp"
using namespace std;

class SnpCheckInStory
	{
	public:
		
		/** Constructor.
		 */
		SnpCheckInStory() {}
		
		/** Destructor
		 */
		virtual ~SnpCheckInStory() {}
		
		ErrorCode	PostStory(const UIDRef& graphicFrameUIDRef);
		
		ErrorCode	ExportStoryToICML(const UIDRef& storyUIDRef, const string icmlName);
		
		int   ExportICMLFromStory(string _attribute, string storyID);
				
	};


/*
 */
ErrorCode SnpCheckInStory::ExportStoryToICML(const UIDRef& storyUIDRef, const string icmlName) {

	ErrorCode result = kFailure;
	do {
		
		//UIDRef storyUIDRef = ::GetUIDRef(textModel);
		//string checkin = AMPCheckin;
		//string createDir = "mkdir " + g_System_WorkspaceDir + "/" + checkin;
		//string IDMLexport = g_SDK_WorkspaceDir + ":" + checkin + ":" + g_Storyid + ".idml";
		string IDMLexport = g_SDK_WorkspaceDir + "\\" + icmlName + ".icml";
		////cout << "IDMLexport: " << IDMLexport << endl;
		PMString fileLocation(IDMLexport.c_str());
		IDFile exportFile(fileLocation);
		SDKFileHelper fileHelper(exportFile);
		
		//InterfacePtr<IPMStream> stream(StreamUtil::CreateFileStreamWrite(idFile, kOpenOut, 'TEXT', 'CWIE'));
		InterfacePtr<IPMStream> stream(StreamUtil::CreateFileStreamWrite(exportFile, kOpenOut, 'TEXT', 'CWIE'));
		ASSERT(stream);
		if(!stream) {
			break;
		}
		stream->Open();
		if (stream->GetStreamState() != kStreamStateGood) {
			break;
		}
		
		stream->SetEndOfStream();
		//ASSERT(options.IsExpandedStructure());
		ASSERT(kINXExpanded.IsExpandedStructure());
		//result = Utils<ISnippetExport>()->ExportInCopyInterchange(stream, uidList);
		result = Utils<ISnippetExport>()->ExportInCopyInterchange(stream, UIDList(storyUIDRef));
		stream->Flush();
		ASSERT(result == kSuccess);
		
		//ISnippetImport
		
		stream->Close();
		//cout << "IDMLexport: " << IDMLexport << endl;
	} while(false);
	
	return result;
}

int SnpCheckInStory::ExportICMLFromStory(string storySessionID, string storyID) {
	// Get the list of stories in this document
	//ErrorCode result = kFailure;
/*	int total_icml = 0;
	IDocument* iDocument = Utils<ILayoutUIUtils>()->GetFrontDocument();
	
	do {
		InterfacePtr<IStoryList> storyList(iDocument, UseDefaultIID());
		ASSERT(storyList);
		if (!storyList) {
			break;
		}
		
		string nameICML[4];
		int    indexUnlocked[g_TextFrameCount];
		int textModelCount = storyList->GetAllTextModelCount();
		for (int32 ii = 0; ii < textModelCount; ii++ )
		{
			//cout << "--**--story: " << ii << endl;
			TextStory_StoryAccess storyAccess = storyList->GetNthTextModelAccess(ii);
			
			// Get the text model of the story.
			UIDRef storyUIDRef = storyList->GetNthTextModelUID(ii);
			//InterfacePtr<ITextModel> textModel(storyUIDRef, UseDefaultIID());
			//ASSERT(textModel);
			//if (!textModel) {
			//	break;
			//}
			
			// get storyID
			//UIDRef storyUIDRef = ::GetUIDRef(textModel);
			InterfacePtr<IIDMLComponentName> compName(storyUIDRef, UseDefaultIID());
			WideString nameStr;
			compName->Get(nameStr);
			string compNameStr;
			StringUtils::ConvertWideStringToUTF8(nameStr, compNameStr);
			
			// get index of story in g_TextFrames
			for (int i = 0; i < g_TextFrameCount; i++) {
				if ((compNameStr.compare(g_TextFrames[i].textframeUID) == 0)) {
					if (storyID.compare(g_TextFrames[i].storyID)==0) {
					
						//cout << "this texframe need to exporting:" << i << endl;
						
						// import content from icml
						//string ICMLExport = g_SDK_WorkspaceDir + ":" + storyID + "_" + g_TextFrames[i].attribute + ".icml";
						string ICMLExport = storyID + "_" + g_TextFrames[i].attribute;		//<--attribute
						//cout << ">>ICMLExport: " << ICMLExport << " - index:" << i << endl;
						//PMString fileLocation(ICMLExport.c_str());
						//IDFile exportFile(fileLocation);
						
						ExportStoryToICML(storyUIDRef, ICMLExport);
						
						// unlock the selected text frame
						//g_TextFrames[storyIndex].isLocked = FALSE;
						indexUnlocked[total_icml] = i;
						
						// assign story session id
						//g_TextFrames[storyIndex].sessionID = storySessionID;
						nameICML[total_icml] = ICMLExport + ".icml";
						total_icml++;
					}
				}
			}
		}
		string ExcuteZip = "cd " + g_System_WorkspaceDir + " && zip " + storyID + " ";
		//lockedIndex = (bool*)malloc(total_icml+1);
		for (int xx = 0; xx <= total_icml; xx++) {
			ExcuteZip = ExcuteZip + nameICML[xx] + " ";
			//lockedIndex[xx] = indexUnlocked[xx];
		}
		//cout << "ExcuteZip: " << ExcuteZip << endl;
		int res = system(ExcuteZip.c_str());
		if (res != 0)
		{
			//cout << "failed to zip file" << endl;
			return 0;
		}
		//cout << "success to zip file" << endl;
		return total_icml;
		//_total_icml = total_icml;
		//*_indexUnlocked = indexUnlocked;
	}while(kFalse);
	return total_icml;
*/
	return 1;
}

// --------------------------------- SnippetRunner framework hooks ---------------------------------------------------

class _SnpRunnerCheckInStory : public SnpRunnable
	{
		
	public:
		// SnippetRunner framework hooks.
		
		/** Constructor.
		 */
		_SnpRunnerCheckInStory();
		
		/** Destructor
		 */
		virtual ~_SnpRunnerCheckInStory();
		
		/** Return kTrue if the snippet can run.
		 @param runnableContext see ISnpRunnableContext for documentation.
		 @return kTrue if a document is open, kFalse otherwise
		 */
		bool16			CanRun(ISnpRunnableContext* runnableContext);
		
		/** Run the snippet.
		 @param runnableContext see ISnpRunnableContext for documentation.
		 @return kSuccess on success, other ErrorCode otherwise.
		 */
		ErrorCode		Run(ISnpRunnableContext* runnableContext);
		
		/**	Don't present this snippet in the framework's UI if the
		 product we are running under is InCopy.
		 @return kTrue if the snippet can be loaded, kFalse otherwise.
		 */
		bool16 CanLoad() const;
		
		
		/** 
		 get the snippet context
		 @return eSnpRunContextType for this snippet
		 */
		virtual ISnipRunSuite::eSnpRunContextType GetContext(void){return ISnipRunSuite::kSnpRunLayoutTargetContext;}
	};

/* Constructor
 */
_SnpRunnerCheckInStory::_SnpRunnerCheckInStory() : SnpRunnable("CheckInStory")
{
	this->SetDescription("check in the selected story to CMS");
	this->SetPreconditions("text frame selected");
	this->SetCategories("sdk_snippet, sdk_text");
}

/* Destructor
 */
_SnpRunnerCheckInStory::~_SnpRunnerCheckInStory()
{
}

/*
 */
bool16 _SnpRunnerCheckInStory::CanRun(ISnpRunnableContext* runnableContext)
{
	bool16 result = kFalse;
	do {
		
		// default is not selected
		g_PrevTextSelected = g_TextSelected;
		g_TextSelected = FALSE;
		
		InterfacePtr<ITextTarget> textTarget(runnableContext, UseDefaultIID());
		if (textTarget == nil) {
			////cout << "textTarget == nil" << endl;
			break;
		}
		
		InterfacePtr<ITextModel> textModel(textTarget->QueryTextModel());
		ASSERT(textModel);
		if (textModel == nil) {
			//cout << "textModel == nil" << endl;
			break;
		}	
		
		// text frame has been selected
		g_TextSelected = TRUE;
		
		// get storyID
		UIDRef storyUIDRef = ::GetUIDRef(textModel);
		InterfacePtr<IIDMLComponentName> compName(storyUIDRef, UseDefaultIID());
		WideString nameStr;
		compName->Get(nameStr);
		string compNameStr;
		StringUtils::ConvertWideStringToUTF8(nameStr, compNameStr);
		g_SelectedTextFrameUID = compNameStr;
		
		////cout << "g_TextFrameCount: " << g_TextFrameCount << endl;
		// check lock of selected story
		for (int i = 0; i < g_TextFrameCount; i++) {
			////cout << "g_SelectedTextFrameUID - g_TextFrames[i].textframeUID: " << g_SelectedTextFrameUID << " - " << g_TextFrames[i].textframeUID << endl;
			if (g_SelectedTextFrameUID.compare(g_TextFrames[i].textframeUID) == 0) {
				//g_TextFrames[i].isLocked = TRUE;
				if (g_TextFrames[i].isLocked == TRUE) {
					////cout << "selected textframe: " << g_TextFrames[i].storyID << " isLocked = TRUE" << endl;	
					//g_TextFrames[i].isLocked = FALSE;
					result = kTrue;
				}
				else {
					//selectionManager->DeselectAll(nil);
					////cout << "selected textframe: " << g_TextFrames[i].storyID << " isLocked = FALSE" << endl;
					//g_TextFrames[i].isLocked = TRUE;
					result = kFalse;
					return result;
				}
				break;
			}
		}
		result = kTrue;
	} while(false);
	
	
	return result;
}

/*
 */
/*
ErrorCode _SnpRunnerCheckInStory::Run(ISnpRunnableContext* runnableContext)
{
	
	//printf("this is _SnpRunnerCheckInStory::Run \n");
	
	ErrorCode status = kFailure;
	//RangeProgressBar progbar("Please wait...", 0, 100, kTrue, kFalse, nil, kFalse);
	
	do {
		SnpCheckInStory instance;
		
		// Find the selected text model
		InterfacePtr<ITextTarget> textTarget(runnableContext, UseDefaultIID());
		if (textTarget == nil) {
			//cout << "textTarget is nil" << endl;
			break;
		}
		InterfacePtr<ITextModel> textModel(textTarget->QueryTextModel());
		ASSERT(textModel);
		if (textModel == nil) {
			//cout << "textModel == nil" << endl;
			break;
		}		
		
		// get storyID
		UIDRef storyUIDRef = ::GetUIDRef(textModel);
		InterfacePtr<IIDMLComponentName> compName(storyUIDRef, UseDefaultIID());
		WideString nameStr;
		compName->Get(nameStr);
		string compNameStr;
		StringUtils::ConvertWideStringToUTF8(nameStr, compNameStr);
		
		// get id and index of story in g_TextFrames
		int storyIndex = -1;
		string storyID = "";
		string attribute = "";
		for (int i = 0; i < g_TextFrameCount; i++) {
			//size_t slashIndex = g_TextFramesID[i].find("/");
			//string textFrameUID = g_TextFramesID[i].substr(0, slashIndex);
			////cout << "textFrameUID: " << textFrameUID << endl;
			//if (compNameStr.compare(textFrameUID) == 0) {
			if (compNameStr.compare(g_TextFrames[i].textframeUID) == 0) {
				
				// get storyID from g_TextFramesID[i]
				//storyID = g_TextFramesID[i].substr(slashIndex+1, g_TextFramesID[i].length());
				storyID = g_TextFrames[i].storyID;
				attribute = g_TextFrames[i].attribute;
				////cout << "storyID: " << storyID << endl;
				storyIndex = i;
				break;
			}
		}
		
		if (storyID.length() < 1) // can't get storyID, so break
			break;
		
		//bool *LockedFlags;
		int total_icml = instance.ExportICMLFromStory(g_TextFrames[storyIndex].sessionID, storyID);
#if 0
		//progbar.SetPosition(10);
		
		// export story to icml
		instance.ExportStoryToICML(storyUIDRef, storyID);
		//progbar.SetPosition(40);
		
		// do http request to post data 
		//HTTPRequestHelper::PostStoryContentToCMS(storyContentStr.c_str(), storyID.c_str());
		
		string pathFile = g_System_WorkspaceDir + "/" + storyID + ".icml";
		//Bool8 res = HTTPRequestHelper::PostStoryContentToCMS(storyID, pathFile, g_TextFrames[storyIndex].sessionID);
		Bool8 res = HTTPRequestHelper::PostStoryContentToCMS(g_Issueid, storyID, pathFile, g_TextFrames[storyIndex].sessionID);
#endif
		string pathFile = g_System_WorkspaceDir + "/" + storyID + ".zip";
		//Bool8 res = HTTPRequestHelper::PostStoryContentToCMS(storyID, pathFile, g_TextFrames[storyIndex].sessionID);
		//Bool8 res = HTTPRequestHelper::PostStoryContentToCMS(g_Issueid, storyID, pathFile, g_TextFrames[storyIndex].sessionID);
		Bool8 res = TRUE;
		if(res == TRUE)
		{
#if 0
			 AMPCAlert::ModalAlert
			 (
			 PMString("Check in success"),	// Alert string
			 kOKString, 					// OK button
			 kNullString, 					// No second button
			 kNullString, 					// No third button
			 kNoNeedToWaitForDialog,		// Set OK button to default
			 CAlert::eNoIcon				// No icon.
			 );
#endif
			//ExcuteRM = "cd " + g_System_WorkspaceDir + " && rm -r -f *";
			//system(ExcuteRM.c_str());
			
			// release lock 
			g_TextSelected = TRUE;
			//g_TextFrames[storyIndex].isLocked = FALSE;
			//g_TextFrames[storyIndex].sessionID = "";
			for (int i = 0; i < g_TextFrameCount; i++) {
				//size_t slashIndex = g_TextFramesID[i].find("/");
				//string textFrameUID = g_TextFramesID[i].substr(0, slashIndex);
				////cout << "textFrameUID: " << textFrameUID << endl;
				//if (compNameStr.compare(textFrameUID) == 0) {
				if (storyID.compare(g_TextFrames[i].storyID) == 0) {
					g_TextFrames[i].isLocked = FALSE;
					g_TextFrames[i].sessionID = "";
				}
			}
			AMPUtils::SaveDocument();	//Toan added here
		}
		else
		{
			g_TextSelected = FALSE;
			AMPCAlert::ModalAlert
			(
			 PMString("Audience Media InDesign Plug-in\n\nFailed to check in\n\nPlease try again"),	// Alert string
			 kOKString, 					// OK button
			 kNullString, 					// No second button
			 kNullString, 					// No third button
			 kNoNeedToWaitForDialog,		// Set OK button to default
			 CAlert::eNoIcon				// No icon.
			 );
		}
		g_PrevTextSelected = g_TextSelected;
	} while(false);
	return status;
}
*/
UIDRef tempFrameCheckedIn = UIDRef::gNull;
ErrorCode _SnpRunnerCheckInStory::Run(ISnpRunnableContext* runnableContext)	//<--20121210attribute
{
	
	//printf("this is _SnpRunnerCheckInStory::Run \n");
	
	ErrorCode status = kFailure;
	//RangeProgressBar progbar("Please wait...", 0, 100, kTrue, kFalse, nil, kFalse);
	
	do {
		SnpCheckInStory instance;
		
		// Find the selected text model
		InterfacePtr<ITextTarget> textTarget(runnableContext, UseDefaultIID());
		if (textTarget == nil) {
			//cout << "textTarget is nil" << endl;
			break;
		}
		InterfacePtr<ITextModel> textModel(textTarget->QueryTextModel());
		ASSERT(textModel);
		if (textModel == nil) {
			//cout << "textModel == nil" << endl;
			break;
		}		

		// get storyID
		UIDRef storyUIDRef = ::GetUIDRef(textModel);
		InterfacePtr<IIDMLComponentName> compName(storyUIDRef, UseDefaultIID());
		WideString nameStr;
		compName->Get(nameStr);
		string compNameStr;
		StringUtils::ConvertWideStringToUTF8(nameStr, compNameStr);
		
		// get id and index of story in g_TextFrames
		int storyIndex = -1;
		string storyID = "";
		for (int i = 0; i < g_TextFrameCount; i++) {
			//size_t slashIndex = g_TextFramesID[i].find("/");
			//string textFrameUID = g_TextFramesID[i].substr(0, slashIndex);
			////cout << "textFrameUID: " << textFrameUID << endl;
			//if (compNameStr.compare(textFrameUID) == 0) {
			if (compNameStr.compare(g_TextFrames[i].textframeUID) == 0) {
				
				// get storyID from g_TextFramesID[i]
				//storyID = g_TextFramesID[i].substr(slashIndex+1, g_TextFramesID[i].length());
				storyID = g_TextFrames[i].storyID;
				////cout << "storyID: " << storyID << endl;
				storyIndex = i;
				break;
			}
		}
		
		if (storyID.length() < 1) // can't get storyID, so break
			break;

		//progbar.SetPosition(10);
		
		// export story to icml
		instance.ExportStoryToICML(storyUIDRef, storyID);
		//progbar.SetPosition(40);
		
		// do http request to post data 
		//HTTPRequestHelper::PostStoryContentToCMS(storyContentStr.c_str(), storyID.c_str());
		
		string pathFile = g_System_WorkspaceDir + "\\" + storyID + ".icml";
		//Bool8 res = HTTPRequestHelper::PostStoryContentToCMS(storyID, pathFile, g_TextFrames[storyIndex].sessionID);
		Bool8 res = HTTPRequestHelper::PostStoryContentToCMS(g_Issueid, storyID, pathFile, g_TextFrames[storyIndex].sessionID);
		
		if(res == TRUE)
		{
			//ExcuteRM = "cd " + g_System_WorkspaceDir + " && rm -r -f *";
			//system(ExcuteRM.c_str());
			// release lock 
			g_TextSelected = TRUE;
			g_TextFrames[storyIndex].isLocked = FALSE;
			g_TextFrames[storyIndex].sessionID = "";
			status = kSuccess;
			for (int i = 0; i < g_assignmentPtr.size(); i++) {
				if(storyID == g_assignmentPtr[i].story_id){
					g_assignmentPtr[i]._status = GRAPHICFRAME_AVAILABLE;
					tempFrameCheckedIn =  g_assignmentPtr[i].frameUIDRef;
					break;
				}
			}
		}
		else
		{
			g_TextSelected = FALSE;
			AMPCAlert::ModalAlert
			(
			 PMString("\n\nCheck-in Failed. Please try again"),	// Alert string
			 "OK",							// OK button
			 kNullString, 					// No second button
			 kNullString, 					// No third button
			 kNoNeedToWaitForDialog,		// Set OK button to default
			 1								// No icon.
			 );
		}
		g_PrevTextSelected = g_TextSelected;
	} while(false);
	return status;
}

/*
 */
bool16  _SnpRunnerCheckInStory::CanLoad() const
{
	bool16 result = kTrue;
	if (LocaleSetting::GetLocale().IsProductFS(kInCopyProductFS)) {
		// Text frames can be manipulated under InCopy
		// but we don't load this snippet because there's no pointer tool
		// to select a text frame with. If we loaded the Go button for the
		// snippet would pretty much always be disabled.
		result = kFalse;
	}
	return result;
}

/*	Declare an instance to register the snippet with the framework.
 */
static _SnpRunnerCheckInStory instance_SnpRunnerCheckInStory;
DEFINE_SNIPPET(_SnpRunnerCheckInStory)

//End, SnpCheckInStory.cpp

